package org.needcoke.hs.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.digest.DigestUtil;
import lombok.experimental.UtilityClass;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;

@UtilityClass
public class SignatureUtil {

    public byte[] md5ByteArray(String content, Charset charset) {
        return DigestUtil.md5(content, charset.name());
    }

    public byte[] md5ByteArray(String content) {
        return md5ByteArray(content, StandardCharsets.UTF_8);
    }

    public String md5(String content) {
        return new String(md5ByteArray(content));
    }

    public String md5(String content, Charset charset) {
        byte[] bytes = md5ByteArray(content, charset);
        return new String(bytes);
    }

    public char[] hexCharArray(String content, Charset charset) {
        return HexUtil.encodeHex(md5ByteArray(content, charset));
    }

    public String hex(String content, Charset charset) {
        return new String(hexCharArray(content, charset));
    }

    public char[] hexCharArray(String content) {
        return hexCharArray(content, StandardCharsets.UTF_8);
    }

    public String hex(String content) {
        return hex(content, StandardCharsets.UTF_8);
    }

    public String base64(String content, Charset charset) {
        return Base64.encode(content, charset);
    }

    public String base64(String content) {
        return Base64.encode(content, StandardCharsets.UTF_8);
    }

    public byte[] sha256ByteArray(String content, Charset charset) {
        return DigestUtil.sha256(content, charset.name());
    }

    public String sha256(String content, Charset charset) {
        return new String(sha256ByteArray(content, charset));
    }

    public byte[] sha256ByteArray(String content) {
        return sha256ByteArray(content, StandardCharsets.UTF_8);
    }

    public String sha256(String content) {
        return sha256(content, StandardCharsets.UTF_8);
    }

    public PrivateKey getPrivateKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] byteKey = java.util.Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(byteKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(spec);
    }

    public String sha256WithRSA(String content, String key) throws Exception{
        Signature signature = Signature.getInstance("sha256WithRSA");
        signature.initSign(getPrivateKey(key));
        signature.update(content.getBytes(StandardCharsets.UTF_8));
        return new String(signature.sign());
    }

    public String rsa2(String content, String key) throws Exception{
        return sha256WithRSA(content,key);
    }

    public String sha1WithRSA(String content, String key) throws Exception {
        Signature signature = Signature.getInstance("sha1WithRSA");
        signature.initSign(getPrivateKey(key));
        signature.update(content.getBytes(StandardCharsets.UTF_8));
        return new String(signature.sign());
    }

    public String rsa(String content, String key) throws Exception {
        return sha1WithRSA(content, key);
    }

}
